{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 94,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "声道数:  1\n",
      "量化位数[byte]:  2\n",
      "采样频率[Hz]:  16000\n",
      "采样点数:  79840\n",
      "声音时长[s]:  4.99\n",
      "people\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Users\\CYT\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:22: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead\n"
     ]
    }
   ],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import wave\n",
    "\n",
    "class Wav_FFT(object):\n",
    "    '''\n",
    "    对音频数据做fft，然后判断是否是人类的声音。\n",
    "    '''\n",
    "    def __init__(self, wav_path=''):\n",
    "        self.path = wav_path\n",
    "        \n",
    "    def read_wav(self):\n",
    "        with  wave.open(self.path, \"rb\") as f:\n",
    "            parameters = f.getparams()\n",
    "            self.nchannels, self.sampwidth, self.framerate, self.nframes = parameters[:4]\n",
    "            self.time_len = self.nframes*1.0 / self.framerate #声音时长\n",
    "            print(\"声道数: \", self.nchannels) #声道数：可以是单声道或者是双声道\n",
    "            print(\"量化位数[byte]: \", self.sampwidth)#量化位数：一次采样所采集的数据的字节数\n",
    "            print(\"采样频率[Hz]: \", self.framerate) #采样频率：一秒内对声音信号的采集次数，常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz\n",
    "            print(\"采样点数: \", self.nframes)#采样点数\n",
    "            print(\"声音时长[s]: \", round(self.time_len,3))#声音时长\n",
    "            # 读取波形数据\n",
    "            str_data = f.readframes(self.nframes)\n",
    "            wave_data = np.fromstring(str_data, dtype=np.short)\n",
    "            wave_data.shape = -1, self.nchannels\n",
    "            self.wave_data = wave_data.T\n",
    "            \n",
    "    def FFT(self):\n",
    "        yf = np.fft.fft(self.wave_data,self.nframes)# FFT\n",
    "        bias =  (yf[:, 0] / self.nframes).real\n",
    "        yf_amplitude = np.abs(yf)* (2.0/self.nframes)\n",
    "        yf_amplitude[:, 0] = bias #直流分量(0 Hz处)修正\n",
    "        self.yf_amplitude = yf_amplitude[:, 0:self.nframes//2]#有效信息只有一半\n",
    "        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)\n",
    "        #ts.plot(figsize=(30,6))\n",
    "\n",
    "    def plot(self):\n",
    "        #self.freq = np.arange(0,self.nframes//2) * self.framerate / self.nframes #实际频率\n",
    "        start = int(200 / (self.framerate / self.nframes)) # 人类最低频率\n",
    "        end = int(1100 / (self.framerate / self.nframes))   # 人类发生最高频率\n",
    "        human_rate = self.yf_amplitude[0][start:end]\n",
    "        x = 0\n",
    "        for i in range(len(human_rate)):\n",
    "            #print(human_rate[i])\n",
    "            if human_rate[i] >= 10.0:\n",
    "                x = x+1\n",
    "        #print(x)\n",
    "        peo_label = 0\n",
    "        if x >= 1600.0:\n",
    "            label = 'people'\n",
    "            #print(label)\n",
    "        else:\n",
    "            label = 'not people'\n",
    "            #print(label)\n",
    "        return label\n",
    "  \n",
    "        \n",
    "if __name__ == \"__main__\":\n",
    "    wav = Wav_FFT(wav_path='audio_wav_2/linkunling2/linkunling21583301748.wav')\n",
    "    wav.read_wav()\n",
    "    wav.FFT()\n",
    "    result = wav.plot()\n",
    "    print(result)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 92,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "D:\\Users\\CYT\\Anaconda3\\lib\\site-packages\\ipykernel_launcher.py:22: DeprecationWarning: The binary mode of fromstring is deprecated, as it behaves surprisingly on unicode inputs. Use frombuffer instead\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "['people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people', 'people']\n",
      "1.0 77 77\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "if __name__ == \"__main__\":\n",
    "    #file_name = 'audio_wav/taifei' #62\n",
    "    #file_name = 'audio_wav/xiefei' #54\n",
    "    #file_name = 'audio_wav/surroundings2' \n",
    "    #file_name = 'audio_wav/linkunling' #65 42\n",
    "    #file_name = 'audio_wav/liusong' #60\n",
    "    file_name = 'audio_wav/suboss2' #70 37\n",
    "    result_list = []\n",
    "    for category in os.listdir(file_name):\n",
    "        wav_path = os.path.join(file_name, category)\n",
    "        wav = Wav_FFT(wav_path= wav_path)\n",
    "        wav.read_wav()\n",
    "        wav.FFT()\n",
    "        label = wav.plot()\n",
    "        result_list.append(label)\n",
    "        #if label == 'people':\n",
    "            #print(category, label)\n",
    "    print(result_list)\n",
    "    print(result_list.count('people')/len(os.listdir(file_name)), result_list.count('people'), len(os.listdir(file_name)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np\n",
    "import wave\n",
    "from scipy import signal\n",
    "import pandas as pd \n",
    "\n",
    "class Wav_delta_FFT(object):\n",
    "    '''\n",
    "    先过滤掉一定频率得音频部分，然后再对过滤过的音频做fft，然后再根据过滤后的音频判断其是否含有人类的声音，双重检验。\n",
    "    '''\n",
    "    def __init__(self, wav_path=''):\n",
    "        self.path = wav_path\n",
    "        \n",
    "    def read_wav(self):\n",
    "        with  wave.open(self.path, \"rb\") as f:\n",
    "            parameters = f.getparams()\n",
    "            self.nchannels, self.sampwidth, self.framerate, self.nframes = parameters[:4]\n",
    "            self.time_len = self.nframes*1.0 / self.framerate #声音时长\n",
    "            #print(\"声道数: \", self.nchannels) #声道数：可以是单声道或者是双声道\n",
    "            #print(\"量化位数[byte]: \", self.sampwidth)#量化位数：一次采样所采集的数据的字节数\n",
    "            #print(\"采样频率[Hz]: \", self.framerate) #采样频率：一秒内对声音信号的采集次数，常用的有8kHz, 16kHz, 32kHz, 48kHz, 11.025kHz, 22.05kHz, 44.1kHz\n",
    "            #print(\"采样点数: \", self.nframes)#采样点数\n",
    "            #print(\"声音时长[s]: \", round(self.time_len,3))#声音时长\n",
    "            # 读取波形数据\n",
    "            str_data = f.readframes(self.nframes)\n",
    "            wave_data = np.fromstring(str_data, dtype=np.short)\n",
    "            self.max_wav_data = max(wave_data)\n",
    "            wave_data.shape = -1, self.nchannels\n",
    "            self.wave_data = wave_data.T\n",
    "        return self.max_wav_data\n",
    "            \n",
    "    def delta(self):\n",
    "        #b, a = signal.butter(2, [90 * 2 / 16000, 1200 * 2 / 16000], 'bandpass')\n",
    "        b, a = signal.butter(2, [90 * 2 / 16000, 1100 * 2 / 16000], 'bandpass') ###90,1100可调参\n",
    "        self.wave_data = np.reshape(self.wave_data,(self.wave_data.shape[1],))\n",
    "        filtedData = signal.filtfilt(b, a, self.wave_data)\n",
    "        self.wave_data = np.reshape(filtedData,(1,filtedData.shape[0]))\n",
    "        #print()            \n",
    "    def FFT(self):\n",
    "        '''\n",
    "        求每hz的幅度,即各频率成分积累。\n",
    "        '''\n",
    "        yf = np.fft.fft(self.wave_data,self.nframes)# FFT\n",
    "        bias =  (yf[:, 0] / self.nframes).real\n",
    "        yf_amplitude = np.abs(yf)* (2.0/self.nframes)\n",
    "        yf_amplitude[:, 0] = bias #直流分量(0 Hz处)修正\n",
    "        self.yf_amplitude = yf_amplitude[:, 0:self.nframes//2]#有效信息只有一半\n",
    "        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)\n",
    "        #ts.plot(figsize=(30,6))\n",
    "\n",
    "    def plot(self):\n",
    "        #self.freq = np.arange(0,self.nframes//2) * self.framerate / self.nframes #实际频率\n",
    "        #ts = pd.Series(self.yf_amplitude[0] * self.framerate / self.nframes)\n",
    "        #ts.plot(figsize=(30,6))\n",
    "        #start = int(200 / (self.framerate / self.nframes)) # 人类最低频率 #200可调参\n",
    "        start = int(200 / (self.framerate / self.nframes))\n",
    "        end = int(1100 / (self.framerate / self.nframes))   # 人类发生最高频率 #1100，可调参\n",
    "        #print(len(self.yf_amplitude[0]), start, end)\n",
    "        human_rate = self.yf_amplitude[0][start:end]\n",
    "        #print(len(human_rate))\n",
    "        x = 0\n",
    "        for i in range(len(human_rate)):\n",
    "            #print(human_rate[i])\n",
    "            if human_rate[i] >=10:#10可调参\n",
    "                x = x+1\n",
    "        peo_label = 0\n",
    "        if x >= 1600.0:#1600可调参\n",
    "            label = 'people'\n",
    "            #print(label)\n",
    "        else:\n",
    "            label = 'not people'\n",
    "            #print(label)\n",
    "        return label\n",
    "  \n",
    "        \n",
    "# if __name__ == \"__main__\":\n",
    "#     wav = Wav_FFT(wav_path='audio_wav_2/linkunling2/linkunling21583301748.wav')\n",
    "#     #wav = Wav_FFT(wav_path='audio_wav/surroundings/surrounding1su1578565858.wav')\n",
    "#     #wav = Wav_FFT(wav_path='audio_wav_2/surroundings2/surroundings21583303827.wav')\n",
    "#     wav.read_wav()\n",
    "#     wav.delta()\n",
    "#     wav.FFT()\n",
    "#     wav.plot()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "audio_wav/taifei 1.0 62 62\n",
      "audio_wav/linkunling 1.0 65 65\n",
      "audio_wav/liusong 1.0 60 60\n",
      "audio_wav/suboss 1.0 37 37\n",
      "audio_wav/surroundings 0.6736842105263158 64 95\n",
      "---------------------------------------------\n",
      "准确率： 0.5642317380352645 [62, 65, 60, 37] 224\n",
      "准确率： 0.3386243386243386\n"
     ]
    }
   ],
   "source": [
    "import os\n",
    "import warnings\n",
    "\n",
    "warnings.filterwarnings('ignore')\n",
    "if __name__ == \"__main__\":\n",
    "#     people_file_list = ['audio_wav/taifei', 'audio_wav/xiefei', 'audio_wav/linkunling2',\n",
    "#                  'audio_wav/linkunling', 'audio_wav/liusong','audio_wav/suboss',\n",
    "#                  'audio_wav/suboss2']\n",
    "#     surr_file_list = ['audio_wav/surroundings', 'audio_wav/surroundings2']\n",
    "    people_file_list = ['audio_wav/taifei',  'audio_wav/linkunling', 'audio_wav/liusong','audio_wav/suboss' ]\n",
    "    surr_file_list = ['audio_wav/surroundings']\n",
    "    #file_name = 'audio_wav/taifei' #62\n",
    "    #file_name = 'audio_wav/xiefei' #54\n",
    "    #file_name = 'audio_wav/surroundings' #94  95\n",
    "    #file_name = 'audio_wav/linkunling2' #65 42\n",
    "    #file_name = 'audio_wav/liusong' #60\n",
    "    #file_name = 'audio_wav/suboss' #70 37\n",
    "    #人声共390条音频，下面是测试人声的代码 \n",
    "    max_energy_num = 7000 #不同设备会有不同的影响\n",
    "    result_num = []\n",
    "    for file_name in people_file_list:\n",
    "        result_list = []\n",
    "        for category in os.listdir(file_name):\n",
    "            wav_path = os.path.join(file_name, category)\n",
    "            wav = Wav_delta_FFT(wav_path= wav_path)\n",
    "            max_energy = wav.read_wav()\n",
    "            #print(int(max_energy))\n",
    "            if int(max_energy) > max_energy_num:#可调整\n",
    "                wav.delta()\n",
    "                wav.FFT()\n",
    "                label = wav.plot()\n",
    "                result_list.append(label)\n",
    "            else:\n",
    "                label = 'not people'\n",
    "                result_list.append(label)\n",
    "            #if label == 'people':\n",
    "                #print(category, label)\n",
    "        #print(result_list)\n",
    "        result_num.append(result_list.count('people'))\n",
    "        print(file_name, result_list.count('people')/len(os.listdir(file_name)), result_list.count('people'), len(os.listdir(file_name)))\n",
    "    \n",
    "    \n",
    "    #环境共189条音频，下面是测试环境的代码\n",
    "    result_num2 = []\n",
    "    for file_name in surr_file_list:\n",
    "        result_list = []\n",
    "        for category in os.listdir(file_name):\n",
    "            wav_path = os.path.join(file_name, category)\n",
    "            wav = Wav_delta_FFT(wav_path= wav_path)\n",
    "            max_energy = wav.read_wav()\n",
    "            #print(max_energy)\n",
    "            if max_energy > max_energy_num:#可调整\n",
    "                wav.delta()\n",
    "                wav.FFT()\n",
    "                label = wav.plot()\n",
    "                result_list.append(label)\n",
    "            else:\n",
    "                label = 'not people'\n",
    "                result_list.append(label)\n",
    "            #if label == 'people':\n",
    "                #print(category, label)\n",
    "        #print(result_list)\n",
    "        result_num2.append(result_list.count('not people'))\n",
    "        print(file_name, result_list.count('not people')/len(os.listdir(file_name)), result_list.count('not people'), len(os.listdir(file_name)))\n",
    "    print('---------------------------------------------')\n",
    "    print('准确率：', sum(result_num)/397, result_num,sum(result_num))\n",
    "    print('准确率：', sum(result_num2)/189)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
